package lumis.portal.page.template.acl;

import java.util.List;

import lumis.portal.*;
import lumis.portal.page.*;
import lumis.portal.dao.*;
import lumis.portal.manager.*;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.channel.acl.ChannelPermissions;
import lumis.util.*;
import lumis.util.security.acl.*;

public class PageTemplateAclManager extends AclManager implements IPageTemplateAclManager
{
	public void add(SessionConfig sessionConfig, PageConfig pageTemplateConfig, ITransaction transaction) throws ManagerException, PortalException
	{
		try
		{
			// check permission
			if (!ManagerFactory.getChannelAclManager().checkPermission(sessionConfig, pageTemplateConfig.getChannelId(), ChannelPermissions.MANAGE_PAGE_TEMPLATE_SECURITY, transaction))
				throw new AccessDeniedException();

			// create new acl
			AccessControlList parentAcl = ManagerFactory.getChannelAclManager().get(sessionConfig, pageTemplateConfig.getChannelId(), transaction);
			String aclId = super.add(parentAcl, PageTemplatePermissions.getInheritPermissionsMap(), PageTemplatePermissions.getImplies(), transaction);

			pageTemplateConfig.setAccessControlListId(aclId);
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception err)
		{
			throw new UnexpectedException(err);
		}
	}

	public AccessControlList get(SessionConfig sessionConfig, String pageTemplateId, ITransaction transaction) throws ManagerException, PortalException
	{
		try
		{
			if (!checkPermission(sessionConfig, pageTemplateId, PageTemplatePermissions.MANAGE_PAGE_TEMPLATE_SECURITY, transaction))
				throw new AccessDeniedException();

			return getAclInternal(sessionConfig, pageTemplateId, transaction);
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception err)
		{
			throw new UnexpectedException(err);
		}
	}

	public void update(SessionConfig sessionConfig, String pageTemplateId, AccessControlList acl, ITransaction transaction) throws ManagerException, PortalException
	{
		try
		{
			if (!checkPermission(sessionConfig, pageTemplateId, PageTemplatePermissions.MANAGE_PAGE_TEMPLATE_SECURITY, transaction))
				throw new AccessDeniedException();

			PageConfig pageConfig = ManagerFactory.getPageManager().get(sessionConfig, pageTemplateId, transaction);
			String pageAcl = pageConfig.getAccessControlListId();
			if(!pageAcl.equals(acl.getId()))
				throw new PortalException("STR_INVALID_ACCESS_CONTROL_LIST");
			
			// force implied permissions
			acl.setImpliedPermissions(PageTemplatePermissions.getImplies());

			super.update(acl, transaction);			
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception err)
		{
			throw new UnexpectedException(err);
		}
	}

	public void setInheritance(SessionConfig sessionConfig, String pageTemplateId, boolean inherit, ITransaction transaction) throws ManagerException, PortalException
	{
		try
		{
			if (!checkPermission(sessionConfig, pageTemplateId, PageTemplatePermissions.MANAGE_PAGE_TEMPLATE_SECURITY, transaction))
				throw new AccessDeniedException();

			PageConfig pageConfig = ManagerFactory.getPageManager().get(sessionConfig, pageTemplateId, transaction);
			AccessControlList acl = getAclInternal(sessionConfig, pageTemplateId, transaction);

			// check if inheritance has changed and return if not
			if (inherit == acl.isInheriting())
				return;

			if (inherit)
			{
				AccessControlList parentAcl = ManagerFactory.getChannelAclManager().get(sessionConfig, pageConfig.getChannelId(), transaction);
				acl.inherit(parentAcl, PageTemplatePermissions.getInheritPermissionsMap());
			}
			else
			{
				acl.removeInheritance(AccessControlList.REMOVE_INHERIT_COPY_PERMISSIONS);
			}

			update(sessionConfig, pageTemplateId, acl, transaction);
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception err)
		{
			throw new UnexpectedException(err);
		}
	}

	public void parentAclUpdated(SessionConfig sessionConfig, String parentChannelId, AccessControlList parentChannelAcl, ITransaction transaction) throws ManagerException, PortalException
	{
		try
		{
			if (!ManagerFactory.getChannelAclManager().checkPermission(sessionConfig, parentChannelId, ChannelPermissions.MANAGE_PAGE_TEMPLATE_SECURITY, transaction))
				throw new AccessDeniedException();

			IPageManager pageManager = ManagerFactory.getPageManager();

			List<String> pageIds = pageManager.getIdsByParentChannelId(sessionConfig, parentChannelId, transaction);

			for (String pageId : pageIds)
			{
				PageConfig pageConfig = pageManager.get(sessionConfig, pageId, transaction);
				if(!pageConfig.isTemplate())
					continue;
				
				AccessControlList acl = getAclInternal(sessionConfig, pageId, transaction);

				if (acl.isInheriting())
				{
					acl.inherit(parentChannelAcl, PageTemplatePermissions.getInheritPermissionsMap());
					update(sessionConfig, pageId, acl, transaction );
				}
			}
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	protected AccessControlList getAclInternal(SessionConfig sessionConfig, String pageTemplateId, ITransaction transaction) throws ManagerException, PortalException
	{
		PageConfig pageConfig = ManagerFactory.getPageManager().get(sessionConfig, pageTemplateId, transaction);
		String aclId = pageConfig.getAccessControlListId();
		AccessControlList acl = aclCache.get(aclId);
		if (acl == null)
		{
			acl = DaoFactory.getAccessControlDao().get(aclId, transaction);

			if(acl.isInheriting())
			{
				AccessControlList parentChannelAcl = ManagerFactory.getChannelAclManager().get(sessionConfig, pageConfig.getChannelId(), transaction);
				acl.inherit(parentChannelAcl, PageTemplatePermissions.getInheritPermissionsMap());
			}
			
			acl.setImpliedPermissions(PageTemplatePermissions.getImplies());

			aclCache.put(pageTemplateId, acl);
		}
		return acl;
	}	

	protected int getRequiredPermissions() throws PortalException
	{
		return PageTemplatePermissions.getRequiredPermissions();
	}
}
